package com.xrui.hbaseview.reflection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;

public class JavaReflector {
    //region Variables
    private static final Logger LOG = LoggerFactory.getLogger(JavaReflector.class);
    //endregion

    private JavaReflector() {
    }
    //endregion

    //region Private Methods
    @SuppressWarnings("unchecked")
    private static <T> T newInstance(Class<T> ownerClass, Object[] args) {
        T instance = null;
        Constructor constructor;

        try {
            if(args != null) {
                Class[] argsClass = new Class[args.length];

                for (int i = 0, j = args.length; i < j; i++) {
                    argsClass[i] = args[i].getClass();
                }
                constructor = ownerClass.getConstructor(argsClass);
            } else {
                constructor = ownerClass.getConstructor();
            }

            instance = (T) constructor.newInstance((Object[]) args);
            constructor.setAccessible(true);
        } catch (Exception e) {
            LOG.error("Cannot reflect class: " + ownerClass.getName(), e);
        }
        return instance;
    }
    //endregion

    //region Public Methods
    @SuppressWarnings("unchecked")
    public static <T> T reflect(String className, Object... args) {
        T instance = null;
        try {
            Class clazz = Class.forName(className);
            instance = newInstance((Class<T>) clazz, args);
        } catch (ClassNotFoundException e) {
            LOG.error("Class not found: " + className, e);
        }
        return instance;
    }

    @SuppressWarnings("unchecked")
    public static <T> T reflect(Class clazz, Object... args) {
        return newInstance((Class<T>) clazz, args);
    }
    //endregion
}
